package org.lease.web.config.exception;

import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.lease.common.exception.BizException;
import org.lease.common.result.Result;
import org.lease.common.result.ResultCode;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 默认异常处理
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleException(Exception e) {
        log.error("默认异常处理：{}", e.getMessage(), e);

        return Result.error(ResultCode.ERROR);
    }

    // 业务异常处理
    @ExceptionHandler(BizException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleBizException(BizException e) {
        log.warn("业务异常处理：{}", e.getMessage(), e);

        ResultCode resultCode = e.getResultCode();
        if (resultCode == ResultCode.ERROR) {
            // 返回未归档的错误信息
            return Result.error(e.getMessage());
        }
        // 返回已归档的错误信息
        return Result.error(e.getResultCode());
    }

    // Controller 中 JavaBean 类型参数的校验异常处理
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result MethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        // 拼接错误信息
        StringBuilder sb = new StringBuilder();
        ex.getBindingResult().getAllErrors().forEach(error -> {
            String errorMessage = error.getDefaultMessage();
            sb.append(errorMessage).append(";");
        });
        sb.deleteCharAt(sb.length() - 1);
        String msg = sb.toString();

        log.error("JavaBean 参数校验异常处理：{}", msg);

        return Result.error(msg);
    }

    // Controller 中简单类型参数的校验异常处理
    @ExceptionHandler(ConstraintViolationException.class)
    public Result handleConstraintViolationException(ConstraintViolationException ex) {
        if (StringUtils.hasText(ex.getMessage())) {
            return Result.error(ex.getMessage());
        }
        return Result.error(ResultCode.ERROR);
    }
}
